<template>
  <div class="ace-editor-container fill-height flex-col">
    <!-- 编辑器工具栏 -->
    <div class="flex items-center justify-between p-2 border-b border-gray-200 bg-gray-50">
      <div class="flex-1 items-center space-x-2" style="padding: 5px 5px;">
        <el-select v-model="localMode" @change="handleModeChange" size="small" class="width-100">
          <el-option
            v-for="(label, value) in availableModes" :key="value" :label="label" :value="value"></el-option>
        </el-select>
        <span v-if="showLineCount" class="text-xs text-gray-500">
          行: {{ lineCount }}
        </span>
      </div>
      <div class="flex items-center space-x-2 d-flex gap-8" >
        <el-button size="mini" @click="formatCode"><i class="fa fa-indent mr-1"></i>格式化</el-button>
        <el-button size="mini" @click="toggleFullscreen">
          <i class="fa" :class="isFullscreen ? 'fa-compress' : 'fa-expand'"></i>
          <span v-if="!isFullscreen">全屏</span>
          <span v-else>退出全屏</span>
        </el-button>
      </div>
    </div>

    <!-- 编辑器主体 -->
    <div id="editor" class="fill-width flex-1" :class="{ 'fixed inset-0 z-50': isFullscreen }"></div>
  </div>
</template>

<script>
import ace from 'ace-builds'
import 'ace-builds/src-noconflict/snippets/javascript'
import 'ace-builds/src-noconflict/snippets/sql'
import 'ace-builds/src-noconflict/snippets/html'
import 'ace-builds/src-noconflict/snippets/css'
import 'ace-builds/src-noconflict/snippets/scss'
import 'ace-builds/src-noconflict/snippets/json'
import 'ace-builds/src-noconflict/snippets/java'
import 'ace-builds/src-noconflict/snippets/text'
import 'ace-builds/webpack-resolver'
import 'ace-builds/src-noconflict/ext-language_tools'
import 'ace-builds/src-noconflict/theme-monokai'
import 'ace-builds/src-noconflict/mode-javascript'

// 导入代码格式化库
import { html as htmlBeautify, js as jsBeautify, css as cssBeautify } from 'js-beautify'

export default {
  name: 'AceEditor',
  props: {
    value: {
      type: String,
      default: ''
    },
    mode: {
      type: String,
      default: 'html'
    },
    theme: {
      type: String,
      default: 'monokai'
    },
    fontSize: {
      type: [String, Number],
      default: '14px'
    },
    height: {
      type: String,
      default: '300px'
    },
    showGutter: {
      type: Boolean,
      default: true
    },
    wrap: {
      type: [Boolean, String, Number],
      default: false
    },
    showPrintMargin: {
      type: Boolean,
      default: false
    },
    readOnly: {
      type: Boolean,
      default: false
    },
    showLineCount: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      editor: null,
      isFullscreen: false,
      localMode: this.mode,
      availableModes: {
        html: 'HTML',
        markdown: 'Markdown',
        javascript: 'JavaScript',
        css: 'CSS',
        python: 'Python',
        java: 'Java',
        csharp: 'C#',
        php: 'PHP'
      }
    }
  },
  computed: {
    lineCount() {
      return this.editor ? this.editor.getSession().getLength() : 0;
    }
  },
  watch: {
    // 监听 value 的变化并更新编辑器内容
    value(newVal) {
      if (this.editor && newVal !== this.editor.getValue()) {
        this.editor.setValue(newVal, -1);
      }
    },

    // 监听 localMode 的变化并更新编辑器模式
    localMode(newMode) {
      if (this.editor && newMode) {
        this.editor.getSession().setMode(`ace/mode/${newMode}`);
        this.$emit('update:mode', newMode);
      }
    },

    // 监听其他 prop 的变化并更新编辑器
    theme(newTheme) {
      if (this.editor) this.editor.setTheme(`ace/theme/${newTheme}`);
    },
    fontSize(newSize) {
      if (this.editor) this.editor.setFontSize(newSize);
    },
    showGutter(newVal) {
      if (this.editor) this.editor.renderer.setShowGutter(newVal);
    },
    wrap(newVal) {
      if (this.editor) this.editor.getSession().setUseWrapMode(newVal);
    },
    showPrintMargin(newVal) {
      if (this.editor) this.editor.setShowPrintMargin(newVal);
    },
    readOnly(newVal) {
      if (this.editor) this.editor.setReadOnly(newVal);
    }
  },
  methods: {
    // 初始化编辑器
    initEditor() {
      // 销毁现有编辑器
      if (this.editor) {
        this.editor.destroy();
      }

      // 创建新编辑器
      this.editor = ace.edit("editor");
      this.editor.setTheme(`ace/theme/${this.theme}`);
      this.editor.getSession().setMode(`ace/mode/${this.localMode}`);
      this.editor.setValue(this.value, -1);
      this.editor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        fontSize: this.fontSize,
        showGutter: this.showGutter,
        showPrintMargin: this.showPrintMargin
      });
      this.editor.getSession().setUseWrapMode(this.wrap);
      this.editor.setReadOnly(this.readOnly);

      // 监听编辑器内容变化
      this.editor.getSession().on('change', () => {
        const content = this.editor.getValue();
        this.$emit('input', content);
        this.$emit('change', content);
      });

      // 配置全屏编辑
      document.addEventListener('keydown', this.handleKeydown);
    },

    // 销毁编辑器
    destroyEditor() {
      if (this.editor) {
        this.editor.destroy();
        document.removeEventListener('keydown', this.handleKeydown);
        this.editor = null;
      }
    },

    // 格式化代码
    formatCode() {
      if (!this.editor || this.readOnly) return;

      try {
        const content = this.editor.getValue();
        let formattedContent = content;

        // 根据当前模式选择合适的格式化器
        switch (this.localMode) {
          case 'html':
            formattedContent = htmlBeautify(content, {
              ...this.formatOptions,
              indent_inner_html: true,
              extra_liners: ['head', 'body', '/html']
            });
            break;
          case 'javascript':
            formattedContent = jsBeautify(content, {
              ...this.formatOptions,
              brace_style: 'collapse,preserve-inline'
            });
            break;
          case 'json':
            formattedContent = jsBeautify(content, {
              ...this.formatOptions,
              brace_style: 'expand',
              space_in_empty_paren: true
            });
            break;
          case 'css':
          case 'scss':
            formattedContent = cssBeautify(content, this.formatOptions);
            break;
          case 'python':
            // 模拟 Python 格式化 (使用 4 个空格缩进)
            formattedContent = content
              .split('\n')
              .map(line => {
                // 计算当前行的缩进级别
                const indent = line.match(/^\s*/)[0].length;
                // 计算新的缩进 (使用 4 个空格)
                const newIndent = ' '.repeat(Math.floor(indent / this.formatOptions.indent_size) * 4);
                // 返回带有新缩进的行
                return newIndent + line.trimLeft();
              })
              .join('\n');
            break;
          case 'java':
          case 'csharp':
          case 'php':
            // 对其他语言使用基本格式化
            formattedContent = jsBeautify(content, {
              ...this.formatOptions,
              indent_size: 4,
              brace_style: 'collapse'
            });
            break;
          default:
            this.$message({
              type: 'warning',
              message: `代码格式化功能暂不支持 ${this.availableModes[this.localMode]} 语言`
            });
            return;
        }

        // 获取当前选择范围
        const selectionRange = this.editor.getSelectionRange();

        // 设置格式化后的内容
        this.editor.setValue(formattedContent, -1);

        // 如果有选中的文本，尝试恢复选择范围
        if (!selectionRange.isEmpty()) {
          this.editor.getSelection().setRange(selectionRange);
        } else {
          // 如果没有选中文本，恢复光标位置
          this.editor.gotoLine(selectionRange.start.row + 1, selectionRange.start.column, false);
        }

        // 通知用户
        this.$message({
          type: 'success',
          message: '代码已格式化'
        });
      } catch (error) {
        console.error('代码格式化失败:', error);
        this.$message({
          type: 'error',
          message: '代码格式化失败'
        });
      }
    },

    // 切换全屏模式
    toggleFullscreen() {
      this.isFullscreen = !this.isFullscreen;

      // 更新编辑器大小
      setTimeout(() => {
        this.editor.resize();
      }, 100);
    },

    // 处理键盘事件
    handleKeydown(e) {
      // ESC 键退出全屏
      if (e.keyCode === 27 && this.isFullscreen) {
        this.toggleFullscreen();
      }

      // F11 键切换全屏
      if (e.keyCode === 122) {
        e.preventDefault();
        this.toggleFullscreen();
      }
    },

    // 处理模式变更
    handleModeChange() {
      this.$emit('mode-change', this.localMode);
    },

    // 编辑器公共方法：获取内容
    getValue() {
      return this.editor ? this.editor.getValue() : '';
    },

    // 编辑器公共方法：设置内容
    setValue(content) {
      if (this.editor) {
        this.editor.setValue(content, -1);
        this.$emit('input', content);
      }
    },

    // 编辑器公共方法：聚焦
    focus() {
      if (this.editor) {
        this.editor.focus();
      }
    },

    // 编辑器公共方法：跳转到指定行
    gotoLine(lineNumber, column = 0, animate = true) {
      if (this.editor) {
        this.editor.gotoLine(lineNumber, column, animate);
      }
    }
  },
  mounted() {
    // 初始化编辑器
    this.$nextTick(() => {
      this.initEditor();
    });
  },
  beforeDestroy() {
    // 销毁编辑器
    this.destroyEditor();
  }
}
</script>

<style scoped lang="scss">
.ace-editor-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
}

/* 全屏样式 */
.ace-fullscreen {
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100% !important;
  height: 100% !important;
  z-index: 9999;
  margin: 0;
  border: 0;
  border-radius: 0;
}
</style>
